package com.task.job.meter3761;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.entity.Measuringpoint;
import com.entity.Report_electri_Power;
import com.file.service.TerminalService;
import com.interfaces.MeasuringpointDao;
import com.interfaces.Report_electri_PowerDao;
import com.protocol.sentjson.JsonResult;
import com.protocol.sentjson.SocketData;
import com.protocolterminal.ProtocolTerminalService;
import com.report.service.TaskRecordReport_ele_Service;
import com.task.service.TaskRecordService;

@Component
public class MeterDailyFreezing implements Job {

	@Autowired
	private MeasuringpointDao measuringpointDao;
	@Autowired
	private TerminalService terminalservice;
	@Autowired
	private TaskRecordService taskRecordService;
	@Autowired
	private TaskRecordReport_ele_Service recordReport_ele_Service;

	@Autowired
	private Report_electri_PowerDao report_electri_PowerDao;

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		/**
		 * 开始时间
		 * 
		 */
		Date begintime = new Date();
		SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		/**
		 * 总数
		 */
		int totalnum = 0;
		int successnum = 0;

		/**
		 * 获取任务信息
		 */
		JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
		String taskid = jobDataMap.getString("taskid");
		String remark = jobDataMap.getString("remark");
		String[] remarks = remark.split(";");
		Integer terminalid = Integer.valueOf(remarks[0]);

		/**
		 * 获取终端信息，测量点信息
		 */
		List<Measuringpoint> measuringpoints = measuringpointDao.findByTerminalid(terminalid);
		String terminalprotocol = terminalservice.findTerminalprotocolByTerminalid(terminalid);
		String terminaladdress = terminalservice.findTerminaladdressByTerminalid(terminalid);

		/**
		 * 获取时标
		 */
		String datetime = getDatetime(-1);
		// 如果指定时标
		if (remarks.length == 2) {
			datetime = remarks[1];
		}

		/**
		 * 根据是否成功，写数据库,写入任务开始时间及基本信息
		 * 
		 */
		taskRecordService.saveTaskRecord(Integer.valueOf(taskid), terminaladdress, "20" + datetime,
				dateFormater.format(begintime), "", "", "", "");

		/**
		 * 执行任务
		 */
		List<Report_electri_Power> report_electri_Powers = new ArrayList<>();
		// 序号从0开始
		int pseq = 0;
		// 逐条发送
		for (Measuringpoint measuringpoint : measuringpoints) {

			ProtocolTerminalService protocolTerminalService = new ProtocolTerminalService();
			String sentframe = protocolTerminalService.Encode(Integer.valueOf(terminalprotocol), "0D",
					new com.protocolterminal.base.Seq(0, 1, 1, 1, pseq).toString(),
					Arrays.asList(measuringpoint.getMeasuringpointnumber()), Arrays.asList("0114".split("-")),
					Arrays.asList(datetime.split(";")), "", 1, 11, terminaladdress);

			// 发送
			String returndata = sent(taskid, measuringpoints, terminaladdress, pseq, sentframe);
			// 解析
			if (returndata != null && !returndata.equals("")) {
				String decodedata = protocolTerminalService.Decode(Integer.valueOf(terminalprotocol), sentframe,
						returndata);

				if (decodedata != null && decodedata.split("-").length == 7) {

					String[] datas = decodedata.split("-");

					Report_electri_Power report_electri_Power = new Report_electri_Power();

					// 时间转为标准
					SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
					String time1 = "";
					String time2 = "";
					try {
						// 时标
						time1 = dateFormater.format(simpleDateFormat.parse("20" + datas[0] + "000000"));
						// 超表时间
						time2 = dateFormater.format(simpleDateFormat.parse("20" + datas[1] + "00"));
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}

					// 保存信息
					report_electri_Power.setTerminaladdress(terminaladdress);
					report_electri_Power.setMeteraddress(String.valueOf(measuringpoint.getMeterid()));
					report_electri_Power.setTime(time1);
					report_electri_Power.setCode("F161");
					report_electri_Power.setName("日冻结数据");
					report_electri_Power.setValue1(datas[2]);
					report_electri_Power.setValue2(datas[3]);
					report_electri_Power.setValue3(datas[4]);
					report_electri_Power.setValue4(datas[5]);
					report_electri_Power.setValue5(datas[6]);
					report_electri_Power.setGettime(time2);
					report_electri_Power.setUpdatetime(dateFormater.format(new Date().getTime()));

					report_electri_Powers.add(report_electri_Power);
					successnum++;
				}
			}
			pseq++;
			totalnum++;
		}
		// 保存原始数据及成功率
		DecimalFormat decimalFormat = save(begintime, dateFormater, totalnum, successnum, taskid, terminaladdress,
				report_electri_Powers);

		// 计算用量
		get_use(dateFormater, terminaladdress, report_electri_Powers, decimalFormat);

	}

	private DecimalFormat save(Date begintime, SimpleDateFormat dateFormater, int totalnum, int successnum,
			String taskid, String terminaladdress, List<Report_electri_Power> report_electri_Powers) {
		// 计算成功率
		Double rate = successnum / Double.valueOf(String.valueOf(totalnum));
		DecimalFormat decimalFormat = new DecimalFormat("##.##");
		String successrate = decimalFormat.format(rate * 100) + "%";

		// 根据是否成功，写数据库,写入任务开始时间及基本信息
		taskRecordService.updateTaskRecordItem(Integer.valueOf(taskid), dateFormater.format(begintime),
				dateFormater.format(new Date().getTime()), String.valueOf(successnum), successrate,
				String.valueOf(totalnum), terminaladdress);

		// 删除老的记录
		if (report_electri_Powers.size() > 0) {
			recordReport_ele_Service.delectdata(terminaladdress, report_electri_Powers.get(0).getTime(), "F161", "DD");
		}
		// 保存记录
		report_electri_PowerDao.save(report_electri_Powers);
		return decimalFormat;
	}

	/**
	 * @Title: MeterDailyFreezing.java
	 * @Description: 获取用量
	 * @param dateFormater
	 * @param terminaladdress
	 * @param report_electri_Powers
	 * @param decimalFormat
	 */
	private void get_use(SimpleDateFormat dateFormater, String terminaladdress,
			List<Report_electri_Power> report_electri_Powers, DecimalFormat decimalFormat) {
		if (report_electri_Powers.size() > 0) {
			Map<String, Object> beformap = new HashMap<>();
			Map<String, Object> aftermap = new HashMap<>();
			// 前一天
			List<Report_electri_Power> befordate = recordReport_ele_Service.listByTimeAndTerminaladdress_daybefore(
					report_electri_Powers.get(0).getTime(), terminaladdress, "F161", "DD");

			if (befordate.size() > 0) {
				for (Report_electri_Power report_electri_Power2 : befordate) {
					beformap.put(report_electri_Power2.getMeteraddress(), report_electri_Power2);
				}
			}
			// 后一天
			List<Report_electri_Power> afterdate = recordReport_ele_Service.listByTimeAndTerminaladdress_dayafter(
					report_electri_Powers.get(0).getTime(), terminaladdress, "F161", "DD");

			if (afterdate.size() > 0) {
				for (Report_electri_Power report_electri_Power2 : afterdate) {
					aftermap.put(report_electri_Power2.getMeteraddress(), report_electri_Power2);
				}
			}

			List<Report_electri_Power> report_electri_Powers_use = new ArrayList<>();
			if (afterdate.size() > 0 || befordate.size() > 0) {
				for (Report_electri_Power report_electri_Power : report_electri_Powers) {
					// 前一天
					if (beformap.getOrDefault(report_electri_Power.getMeteraddress(), null) != null) {
						Report_electri_Power usebefor = (Report_electri_Power) beformap
								.get(report_electri_Power.getMeteraddress());

						Double use1 = Double.valueOf(report_electri_Power.getValue1())
								- Double.valueOf(usebefor.getValue1());
						Double use2 = Double.valueOf(report_electri_Power.getValue2())
								- Double.valueOf(usebefor.getValue2());
						Double use3 = Double.valueOf(report_electri_Power.getValue3())
								- Double.valueOf(usebefor.getValue3());
						Double use4 = Double.valueOf(report_electri_Power.getValue4())
								- Double.valueOf(usebefor.getValue4());
						Double use5 = Double.valueOf(report_electri_Power.getValue5())
								- Double.valueOf(usebefor.getValue5());

						usebefor.setValue1(decimalFormat.format(use1));
						usebefor.setValue2(decimalFormat.format(use2));
						usebefor.setValue3(decimalFormat.format(use3));
						usebefor.setValue4(decimalFormat.format(use4));
						usebefor.setValue5(decimalFormat.format(use5));

						usebefor.setCode("F161_use");
						usebefor.setTime(report_electri_Power.getTime());
						usebefor.setGettime(dateFormater.format(new Date().getTime()));
						usebefor.setUpdatetime(dateFormater.format(new Date().getTime()));
						usebefor.setId(null);

						report_electri_Powers_use.add(usebefor);
					}
					// 后一天
					if (aftermap.getOrDefault(report_electri_Power.getMeteraddress(), null) != null) {
						Report_electri_Power usebafter = (Report_electri_Power) aftermap
								.get(report_electri_Power.getMeteraddress());

						Double use1 = Double.valueOf(usebafter.getValue1())
								- Double.valueOf(report_electri_Power.getValue1());
						Double use2 = Double.valueOf(usebafter.getValue2())
								- Double.valueOf(report_electri_Power.getValue2());
						Double use3 = Double.valueOf(usebafter.getValue3())
								- Double.valueOf(report_electri_Power.getValue3());
						Double use4 = Double.valueOf(usebafter.getValue4())
								- Double.valueOf(report_electri_Power.getValue4());
						Double use5 = Double.valueOf(usebafter.getValue5())
								- Double.valueOf(report_electri_Power.getValue5());

						usebafter.setValue1(decimalFormat.format(use1));
						usebafter.setValue2(decimalFormat.format(use2));
						usebafter.setValue3(decimalFormat.format(use3));
						usebafter.setValue4(decimalFormat.format(use4));
						usebafter.setValue5(decimalFormat.format(use5));

						usebafter.setCode("F161_use");
						usebafter.setGettime(dateFormater.format(new Date().getTime()));
						usebafter.setUpdatetime(dateFormater.format(new Date().getTime()));
						usebafter.setId(null);

						report_electri_Powers_use.add(usebafter);
					}
					report_electri_PowerDao.save(report_electri_Powers_use);
				}
			}
		}
	}

	private String getDatetime(int idate) {
		SimpleDateFormat dft = new SimpleDateFormat("yy-MM-dd");
		Date beginDate = new Date();
		Calendar date = Calendar.getInstance();
		date.setTime(beginDate);
		date.set(Calendar.DATE, date.get(Calendar.DATE) + idate);
		String datetime = dft.format(date.getTime());
		return datetime;
	}

	private String sent(String taskid, List<Measuringpoint> measuringpoints, String terminaladdress, int pseq,
			String sentframe) {
		// http请求
		String urlsent = "http://localhost:8000/SocketControl/sent/task";
		RestTemplate restTemplatesent = new RestTemplate();

		// 组发送内容
		JsonResult<SocketData> sentjson = new JsonResult<>();

		SocketData socketData = new SocketData();
		socketData.setTaskid(taskid);
		socketData.setTerminaladdress(terminaladdress);
		socketData.setMessage(sentframe);
		if (pseq == measuringpoints.size() - 1) {
			socketData.setLast(true);
		} else {
			socketData.setLast(false);
		}
		sentjson.setData(socketData);

		// 发送
		@SuppressWarnings("rawtypes")
		ResponseEntity<JsonResult> returnjson = restTemplatesent.postForEntity(urlsent, sentjson, JsonResult.class);
		// 终端不在线，终端通讯中
		if (returnjson.getBody().getState() == 3002 || returnjson.getBody().getState() == 3003) {
			return null;
		}

		// 准备接收
		Date date1 = new Date();
		Date date2 = new Date();

		boolean flag = false;

		String urlback = "http://localhost:8000/SocketControl/receive/task";
		RestTemplate restTemplatereceive = new RestTemplate();

		String returndata = null;
		while (((date2.getTime() - date1.getTime()) < 2 * 60 * 1000) && !flag) {
			@SuppressWarnings("rawtypes")
			ResponseEntity<JsonResult> receiveresult = restTemplatereceive.postForEntity(urlback, sentjson,
					JsonResult.class);
			// 正常返回
			if (receiveresult.getBody().getState() == 3100) {
				@SuppressWarnings("unchecked")
				Map<String, String> map = (Map<String, String>) receiveresult.getBody().getData();

				returndata = map.get("message");
				if (!returndata.equals("")) {
					flag = true;
				}
			}

			try {
				Thread.sleep(1 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			date2 = new Date();
		}
		return returndata;
	}

}
